﻿using Mono.CompilerServices.SymbolWriter;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;

namespace Teal.Compiler {

    #region MemberDefinition

    /// <summary>
    /// 表示一个成员（如方法、字段、类型、包等）定义。
    /// </summary>
    public abstract partial class MemberDefinition {

        #region 代码生成

        /// <summary>
        /// 创建当前类型定义相关的构建器。
        /// </summary>
        public abstract void createTypeBuilder();

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public abstract void emitBody();

        /// <summary>
        /// 关闭并创建当前类型主体。
        /// </summary>
        public abstract void closeTypeBuilder();

        /// <summary>
        /// 将当前成员写入调试符号文件。
        /// </summary>
        /// <param name="file"></param>
        public virtual void writeDebugSymbol(MonoSymbolFile file) {
        }

        #endregion

        #region 属性

        /// <summary>
        /// 获取当前成员的元数据名。
        /// </summary>
        protected string metaName {
            get {

                string name = container == null ? null : container.metaName;
                if (name != null && name.Length > 0) {
                    name += ".";
                }

                name += reference.name;
                if (reference.genericParameterCount > 0) {
                    name += "`" + reference.genericParameterCount;
                }

                return name;
            }
        }

        #endregion

        #region 注解

        /// <summary>
        /// 生成所有注解。
        /// </summary>
        protected void emitAnnotations() {

        }

        #endregion

        #region 泛型

        /// <summary>
        /// 创建并生成泛型参数。
        /// </summary>
        /// <param name="genericParameters"></param>
        /// <returns></returns>
        protected string[] getGenericParameterNames(List<MemberReference.GenericParameter> gernericParamters) {
            var names = new string[gernericParamters.Count];
            for (int i = 0; i < names.Length; i++) {
                names[i] = gernericParamters[i].name;
            }
            return names;
        }

        protected void appedAllGenericParameters(List<MemberReference.GenericParameter> gernericParamters) {
            // 将所有父级的泛型合并。
            // A<T>.B<U> -> A.B<T, U>
            appendGenericParameters(reference, gernericParamters);
        }

        private static void appendGenericParameters(MemberReference member, List<MemberReference.GenericParameter> gernericParamters) {
            if (member.container != null) {
                appendGenericParameters(member.container, gernericParamters);
            }
            if (member.genericParameters != null) {
                foreach (var genericParameter in member.genericParameters) {
                    gernericParamters.Add(genericParameter);
                }
            }
        }

        /// <summary>
        /// 创建泛型形参的类型。
        /// </summary>
        /// <param name="genericTypeParameterBuilder"></param>
        protected void createGenericParametersBuilder(List<MemberReference.GenericParameter> gernericParamters, GenericTypeParameterBuilder[] genericTypeParameterBuilder) {
            Debug.Assert(gernericParamters.Count == genericTypeParameterBuilder.Length);
            var genericParameters = gernericParamters;
            for (int i = 0; i < genericParameters.Count; i++) {
                genericParameters[i].metaInfo = genericTypeParameterBuilder[i];
            }
        }

        /// <summary>
        /// 生成泛型形参。
        /// </summary>
        /// <param name="genericTypeParameterBuilder"></param>
        protected void emitGenericParameters(Type[] genericTypes) {
            if (genericTypes.Length == 0) {
                return;
            }
            var genericTypeParameterBuilder = (GenericTypeParameterBuilder[])genericTypes;
            List<MemberReference.GenericParameter> tps = ListObjectPool<MemberReference.GenericParameter>.alloc();
            appedAllGenericParameters(tps);

            for (int i = 0; i < tps.Count; i++) {
                emitGenericParameter(tps[i]);
            }

            ListObjectPool<MemberReference.GenericParameter>.free(tps);

        }

        /// <summary>
        /// 生成当前泛型形参。
        /// </summary>
        private void emitGenericParameter(MemberReference.GenericParameter reference) {

            var builder = (GenericTypeParameterBuilder)reference.metaInfo;

            GenericParameterAttributes attr;

            switch (reference.attributes & MemberReference.GenericParameter.Attributes.MEMBER_TYPE_CONSTRAINT) {
                case MemberReference.GenericParameter.Attributes.classConstraint:
                    attr = GenericParameterAttributes.ReferenceTypeConstraint;
                    builder.SetBaseTypeConstraint(typeof(Object));
                    break;
                case MemberReference.GenericParameter.Attributes.structConstraint:
                    attr = GenericParameterAttributes.NotNullableValueTypeConstraint;
                    builder.SetBaseTypeConstraint(typeof(ValueType));
                    break;
                case MemberReference.GenericParameter.Attributes.enumConstraint:
                    attr = GenericParameterAttributes.NotNullableValueTypeConstraint;
                    builder.SetBaseTypeConstraint(typeof(Enum));
                    break;
                default:
                    attr = GenericParameterAttributes.None;
                    builder.SetBaseTypeConstraint(reference.baseClass.metaInfo);
                    break;
            }

            if (reference.hasDefaultConstructorConstraint) {
                attr |= GenericParameterAttributes.DefaultConstructorConstraint;
            }

            if (reference.baseInterfaces != null) {
                var constraints = new Type[reference.baseInterfaces.Count];
                for (int i = 0; i < constraints.Length; i++) {
                    constraints[i] = reference.baseInterfaces[i].metaInfo;
                }
                builder.SetInterfaceConstraints(constraints);
            }

            builder.SetGenericParameterAttributes(attr);
        }

        #endregion

    }

    #endregion

    #region TypeDefinitions

    /// <summary>
    /// 表示一个可以包含子成员的容器成员定义。
    /// </summary>
    public abstract partial class MemberContainerDefinition {

        /// <summary>
        /// 创建当前类型定义相关的构建器。
        /// </summary>
        [DebuggerStepThrough]
        public override void createTypeBuilder() {
            for (var member = members; member != null; member = member.next) {
                member.createTypeBuilder();
            }
        }

        /// <summary>
        /// 生成当前节点的代码。
        /// </summary>
        /// <param name="context">用于存储所有生成数据的上下文对象。</param>
        [DebuggerStepThrough]
        public override void emitBody() {
            for (var member = members; member != null; member = member.next) {
                member.emitBody();
            }
        }

        /// <summary>
        /// 关闭并创建当前主体。
        /// </summary>
        [DebuggerStepThrough]
        public override void closeTypeBuilder() {
            for (var member = members; member != null; member = member.next) {
                member.closeTypeBuilder();
            }
        }

        /// <summary>
        /// 将当前成员写入调试符号文件。
        /// </summary>
        /// <param name="file"></param>
        [DebuggerStepThrough]
        public override void writeDebugSymbol(MonoSymbolFile file) {
            for (var member = members; member != null; member = member.next) {
                member.writeDebugSymbol(file);
            }
        }

    }

    /// <summary>
    /// 表示一个类型（如类、结构、接口）定义。
    /// </summary>
    public abstract partial class TypeDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public TypeBuilder builder {
            get {
                return (TypeBuilder)reference.metaInfo;
            }
            set {
                reference.metaInfo = value;
            }
        }

        /// <summary>
        /// 创建当前类型定义相关的构建器。
        /// </summary>
        public sealed override void createTypeBuilder() {

            // 创建 builder 。
            if (container.reference.memberType == MemberType.@namespace) {
                builder = containerModule.builder.DefineType(metaName, getTypeAttributes());
            } else {
                builder = ((TypeDefinition)container).builder.DefineNestedType(reference.name, getTypeAttributes());
            }

            // 创建泛型形参。
            List<MemberReference.GenericParameter> tps = ListObjectPool<MemberReference.GenericParameter>.alloc();
            base.appedAllGenericParameters(tps);
            if (tps.Count > 0) {
                base.createGenericParametersBuilder(tps, builder.DefineGenericParameters(base.getGenericParameterNames(tps)));
            }
            ListObjectPool<MemberReference.GenericParameter>.free(tps);

            // 创建子类型。
            if ((flags & Flags.hasNestedTypes) != 0) {
                base.createTypeBuilder();
            }
        }

        /// <summary>
        /// 根据当前成员修饰符获取类型属性。
        /// </summary>
        protected virtual TypeAttributes getTypeAttributes() {
            var attrs = container.reference.memberType == MemberType.@namespace ?
                modifiers.hasFlag(Modifiers.@protected | Modifiers.@private) ?
                    modifiers.hasFlag(Modifiers.@protected) ? TypeAttributes.NestedFamily : TypeAttributes.NotPublic : TypeAttributes.Public :
                modifiers.hasFlag(Modifiers.@protected | Modifiers.@private) ?
                    modifiers.hasFlag(Modifiers.@protected) ? TypeAttributes.NestedFamily : TypeAttributes.NestedPrivate : TypeAttributes.NestedPublic;
            //if (!has_static_constructor)
            //    attrs |= TypeAttributes.BeforeFieldInit;
            return attrs;
        }

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public sealed override void emitBody() {

            // 生成注解。
            base.emitAnnotations();

            // 生成泛型参数。
            base.emitGenericParameters(builder.GenericTypeParameters);

            // 生成基类型。
            if (reference.baseClass == null) {
                builder.SetParent(null);
            } else {
                builder.SetParent(reference.baseClass.metaInfo);
            }
            if (reference.baseInterfaces != null) {
                foreach (var baseInterface in reference.baseInterfaces) {
                    builder.AddInterfaceImplementation(baseInterface.metaInfo);
                }
            }

            // 生成子成员。
            base.emitBody();

        }

        /// <summary>
        /// 关闭并创建当前主体。
        /// </summary>
        public sealed override void closeTypeBuilder() {

            if (checkFlag(Flags.closeTypeBuilderCalled)) {
                return;
            }

            // 必须先关闭基类型。
            if (reference.baseClass != null && reference.baseClass.definition != null) {
                reference.baseClass.definition.closeTypeBuilder();
            }

            if (reference.baseInterfaces != null) {
                foreach (var baseInterface in reference.baseInterfaces) {
                    if (baseInterface.definition != null) {
                        baseInterface.definition.closeTypeBuilder();
                    }
                }
            }

            try {
                builder.CreateType();
            } catch (TypeLoadException) {
                // 类型已创建。
            }

            // 关闭子类型。
            if ((flags & Flags.hasNestedTypes) != 0) {
                base.closeTypeBuilder();
            }
        }

        /// <summary>
        /// 将当前成员写入调试符号文件。
        /// </summary>
        /// <param name="file"></param>
        public override void writeDebugSymbol(MonoSymbolFile file) {
            base.writeDebugSymbol(file);
        }
    }

    /// <summary>
    /// 表示一个类定义。
    /// </summary>
    public partial class ClassDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取类型属性。
        /// </summary>
        protected sealed override TypeAttributes getTypeAttributes() {
            var attrs = base.getTypeAttributes() | TypeAttributes.AutoLayout | TypeAttributes.Class;

            if (modifiers.hasFlag(Modifiers.@abstract)) {
                attrs |= TypeAttributes.Abstract;
            }
            if (modifiers.hasFlag(Modifiers.final)) {
                attrs |= TypeAttributes.Sealed;
            }
            if (modifiers.hasFlag(Modifiers.@static)) {
                attrs |= TypeAttributes.Abstract | TypeAttributes.Sealed;
            }

            return attrs;
        }

    }

    /// <summary>
    /// 表示一个结构定义。
    /// </summary>
    public partial class StructDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取类型属性。
        /// </summary>
        protected sealed override TypeAttributes getTypeAttributes() {
            return base.getTypeAttributes() | TypeAttributes.SequentialLayout;
        }

    }

    /// <summary>
    /// 表示一个接口定义。
    /// </summary>
    public partial class InterfaceDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取类型属性。
        /// </summary>
        protected sealed override TypeAttributes getTypeAttributes() {
            return base.getTypeAttributes() | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.Interface;
        }

    }

    /// <summary>
    /// 表示一个枚举定义。
    /// </summary>
    public partial class EnumDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取类型属性。
        /// </summary>
        protected sealed override TypeAttributes getTypeAttributes() {
            return base.getTypeAttributes() | TypeAttributes.Class | TypeAttributes.Sealed;
        }

        ///// <summary>
        ///// 生成当前节点的代码。
        ///// </summary>
        ///// <param name="context">用于存储所有生成数据的上下文对象。</param>
        //public override void emitBody() {

        //    reference.baseClass.metaInfo = typeof(Enum);

        //    //  builder.DefineField(underlyingValueField, UnderlyingType.GetMetaInfo(), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
        //    base.emitBody();

        //}

    }

    /// <summary>
    /// 表示一个扩展定义。
    /// </summary>
    public partial class ExtensionDefinition {

    }

    #endregion

    #region NamespaceDefinitions

    /// <summary>
    /// 表示一个命名空间定义。
    /// </summary>
    public partial class NamespaceDefinition {

    }

    /// <summary>
    /// 表示一个源编译单元。
    /// </summary>
    public partial class SourceUnit {

    }

    /// <summary>
    /// 表示一个模块。
    /// </summary>
    public partial class ModuleDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public ModuleBuilder builder {
            get { return (ModuleBuilder)reference.metaInfo; }
            set { reference.metaInfo = value; }
        }

        /// <summary>
        /// 生成当前模块的代码。
        /// </summary>
        public void emit() {
            createTypeBuilder();
            emitBody();
            closeTypeBuilder();
        }

        /// <summary>
        /// 用于自动生成成员所使用的计数器。
        /// </summary>
        public int counter;

        /// <summary>
        /// 创建当前类型定义相关的构建器。
        /// </summary>
        public override void createTypeBuilder() {
            builder = Compiler.currentPackage.builder.DefineDynamicModule(System.IO.Path.GetFileName(Compiler.options.outputPath));
            base.createTypeBuilder();
        }

        /// <summary>
        /// 生成当前节点的代码。
        /// </summary>
        /// <param name="context">用于存储所有生成数据的上下文对象。</param>
        public override void emitBody() {
            base.emitBody();
        }

        /// <summary>
        /// 关闭并创建当前主体。
        /// </summary>
        public override void closeTypeBuilder() {
            //if (anonymous_types != null) {
            //    foreach (var atypes in anonymous_types)
            //        foreach (var at in atypes.Value)
            //            at.closeTypeBuilder();
            //}

            // builder.CreateGlobalFunctions();
            base.closeTypeBuilder();
        }

    }

    #endregion

    #region TypeMemberDefinitions

    /// <summary>
    /// 表示一个类型子成员定义。
    /// </summary>
    public abstract partial class TypeMemberDefinition {

        #region 语义解析

        /// <summary>
        /// 创建当前类型定义相关的构建器。
        /// </summary>
        public sealed override void createTypeBuilder() {
            // 普通成员不需要创建构建器。
        }

        /// <summary>
        /// 关闭并创建当前类型主体。
        /// </summary>
        public sealed override void closeTypeBuilder() {
            // 普通成员不需要关闭构建器。
        }

        #endregion

        protected void emitBody(ToplevelBlock body) {

        }

    }

    /// <summary>
    /// 表示一个字段定义。
    /// </summary>
    public partial class FieldDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public FieldBuilder builder {
            get {
                return (FieldBuilder)reference.metaInfo;
            }
            set {
                reference.metaInfo = value;
            }
        }

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public override void emitBody() {

            var isToplever = container.reference.memberType == MemberType.@namespace;

            // 生成修饰符。
            Type[] requiredModifiers = null;
            if (modifiers.hasFlag(Modifiers.@volatile)) {
                requiredModifiers = new Type[] { typeof(IsVolatile) };
            } else if (modifiers.hasFlag(Modifiers.@const)) {
                requiredModifiers = new Type[] { typeof(IsConst) };
            }
            int i = 0;
            for (var variable = variables; variable != null; variable = variable.next, i++) {

                name = variable.name;
                reference = references[i];

                // 生成属性。
                var attrs = modifiers.hasFlag(Modifiers.@protected | Modifiers.@private) ?
                    modifiers.hasFlag(Modifiers.@protected) ? FieldAttributes.Family : FieldAttributes.Private :
                    FieldAttributes.Public;
                if (modifiers.hasFlag(Modifiers.@static)) {
                    attrs |= FieldAttributes.Static;
                }
                if (modifiers.hasFlag(Modifiers.final)) {
                    attrs |= FieldAttributes.InitOnly;
                }
                if (modifiers.hasFlag(Modifiers.@const)) {
                    attrs |= FieldAttributes.Static | FieldAttributes.Literal;
                }

                // 创建生成器。
                if (isToplever) {
                    // todo
                    // builder = parentModule.builder.DefineUninitializedData()
                    Compiler.notImplement(this, "不支持全局字段");
                } else {
                    builder = containerType.builder.DefineField(reference.name, reference.returnType.metaInfo, requiredModifiers, null, attrs);
                }

                base.emitAnnotations();

                var fixedBuffer = reference.getAnnotation(PredefinedTypes.System_RunTime_FixedBufferAnnotation);
                if (fixedBuffer != null) {

                    //// Create nested fixed buffer container
                    //string name = String.Format("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
                    //fixed_buffer_type = Parent.TypeBuilder.DefineNestedType(name,
                    //    TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
                    //    Compiler.BuiltinTypes.ValueType.GetMetaInfo());

                    //var ffield = fixed_buffer_type.DefineField(FixedElementName, MemberType2.GetMetaInfo(), FieldAttributes.Public);

                    //FieldBuilder = Parent.TypeBuilder.DefineField(Name, fixed_buffer_type, ModifiersExtensions.FieldAttr(ModFlags));

                    //var element_spec = new FieldReference(null, this, MemberType2, ffield, ModFlags);
                    //spec = new FixedFieldSpec(parentModule, Parent.Definition, this, FieldBuilder, element_spec, ModFlags);

                    //int buffer_size = buffer_size_const.Value;

                    //EmitFieldSize(buffer_size);

                    //parentModule.PredefinedAttributes.UnsafeValueType.EmitAttribute(fixed_buffer_type);
                    //parentModule.PredefinedAttributes.CompilerGenerated.EmitAttribute(fixed_buffer_type);
                    //fixed_buffer_type.CreateType();

                    //base.Emit();
                }

                if (modifiers.hasFlag(Modifiers.@const)) {
                    // todo
                    builder.SetConstant(null);
                }

            }

        }

        //void EmitFieldSize(int buffer_size) {
        //    int type_size = BuiltinTypeSpec.GetSize(MemberType2);

        //    AttributeEncoder encoder;

        //    var ctor = parentModule.PredefinedMembers.StructLayoutAttributeCtor.Resolve(startLocation2);
        //    if (ctor == null)
        //        return;

        //    var field_size = parentModule.PredefinedMembers.StructLayoutSize.Resolve(startLocation2);
        //    var field_charset = parentModule.PredefinedMembers.StructLayoutCharSet.Resolve(startLocation2);
        //    if (field_size == null || field_charset == null)
        //        return;

        //    var char_set = CharSet ?? parentModule.DefaultCharSet ?? 0;

        //    encoder = new AttributeEncoder();
        //    encoder.Encode((short)LayoutKind.Sequential);
        //    encoder.EncodeNamedArguments(
        //        new[] { field_size, field_charset },
        //        new Constant[] { 
        //            new IntConstant (Compiler.BuiltinTypes, buffer_size * type_size, startLocation2),
        //            new IntConstant (Compiler.BuiltinTypes, (int) char_set, startLocation2)
        //        }
        //    );

        //    fixed_buffer_type.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray());

        //    //
        //    // Don't emit FixedBufferAttribute attribute for private types
        //    //
        //    if ((ModFlags & Modifiers.@private) != 0)
        //        return;

        //    ctor = parentModule.PredefinedMembers.FixedBufferAttributeCtor.Resolve(startLocation2);
        //    if (ctor == null)
        //        return;

        //    encoder = new AttributeEncoder();
        //    encoder.EncodeTypeName(MemberType2);
        //    encoder.Encode(buffer_size);
        //    encoder.EncodeEmptyNamedArguments();

        //    FieldBuilder.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray());
        //}
    }

    /// <summary>
    /// 表示一个属性或索引器定义。
    /// </summary>
    public abstract partial class PropertyOrIndexerDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public PropertyBuilder builder {
            get {
                return (PropertyBuilder)reference.metaInfo;
            }
            set {
                reference.metaInfo = value;
            }
        }

        /// <summary>
        /// 表示一个属性访问器。
        /// </summary>
        public partial class PropertyAccessor {

            /// <summary>
            /// 获取当前成员对应的构建器。
            /// </summary>
            public MethodBuilder builder {
                get {
                    return (MethodBuilder)reference.metaInfo;
                }
                set {
                    reference.metaInfo = value;
                }
            }

            /// <summary>
            /// 生成当前主体的代码。
            /// </summary>
            public override void emitBody() {

                // builder = container.PartialContainer.

                //MethodAttributes.HideBySig | MethodAttributes.SpecialName
            }
        }

        protected Type[] createParameterTypes() {
            throw new NotImplementedException();
        }

        public override void writeDebugSymbol(MonoSymbolFile file) {
            if (get != null)
                get.writeDebugSymbol(file);

            if (set != null)
                set.writeDebugSymbol(file);
        }
    }

    /// <summary>
    /// 表示一个属性定义。
    /// </summary>
    public partial class PropertyDefinition {

        public sealed override void emitBody() {
            builder = containerType.builder.DefineProperty(reference.name, PropertyAttributes.None, modifiers.hasFlag(Modifiers.@static) ? 0 : CallingConventions.HasThis, reference.returnType.metaInfo, null, null, base.createParameterTypes(), null, null);


            if (getAccessor != null) {
                getAccessor.emitBody();
                builder.SetGetMethod(getAccessor.builder);
            }

            if (setAccessor != null) {
                setAccessor.emitBody();
                builder.SetSetMethod(setAccessor.builder);
            }

        }

    }

    /// <summary>
    /// 表示一个索引器定义。
    /// </summary>
    public partial class IndexerDefinition {

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public override void emitBody() {

        }

    }

    /// <summary>
    /// 表示一个方法或构造函数定义。
    /// </summary>
    public abstract partial class MethodOrConstructorDefinition : IMethodData, IMethodDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public MethodBuilder builder {
            get {
                return (MethodBuilder)reference.metaInfo;
            }
            set {
                reference.metaInfo = value;
            }
        }

        /// <summary>
        /// 根据当前成员修饰符获取方法属性。
        /// </summary>
        /// <returns></returns>
        protected virtual MethodAttributes getMethodAttributes() {
            MethodAttributes attrs = 0;
            if (modifiers.hasFlag(Modifiers.@abstract)) {
                attrs = MethodAttributes.Abstract;
            } else if (modifiers.hasFlag(Modifiers.@override)) {

            } else if (modifiers.hasFlag(Modifiers.@virtual)) {
                attrs = MethodAttributes.Virtual | MethodAttributes.HideBySig;
            } else {
                attrs = MethodAttributes.Final;
            }

            switch (modifiers & (Modifiers.@protected | Modifiers.@private)) {
                case Modifiers.none:
                    attrs |= MethodAttributes.Public;
                    break;
                case Modifiers.@protected:
                    attrs |= MethodAttributes.Family;
                    break;
                default:
                    attrs |= MethodAttributes.Private;
                    break;
            }

            if (modifiers.hasFlag(Modifiers.final)) {
                attrs |= MethodAttributes.Final;
            }

            return attrs;
        }

        void emitParameters(MethodBuilder mb, ConstructorBuilder cb) {

            // 定义参数。
            var paramCount = reference.parameters.Length;
            if (paramCount > 0 && reference.parameters[paramCount - 1].variableType == VariableType.argListParameter) {
                paramCount--;
            }

            var ps = new Type[paramCount];
            for (int i = 0; i < paramCount; i++) {
                var parameter = reference.parameters[i];
                var type = parameter.type.metaInfo;
                if (parameter.variableType == VariableType.refParameter ||
                    parameter.variableType == VariableType.outParameter) {
                    type = type.MakeByRefType();
                }
                ps[i] = type;
            }
            if (cb == null) {
                mb.SetParameters(ps);
            } else {
                
            }
            for (int i = 0; i < paramCount; i++) {
                var parameter = reference.parameters[i];

                ParameterAttributes attrs = parameter.defaultValue != null ? ParameterAttributes.Optional : ParameterAttributes.None;

                ParameterBuilder pb;

                if (cb == null) {
                    pb = mb.DefineParameter(i + 1, attrs, parameter.name);
                } else {
                    pb = cb.DefineParameter(i + 1, attrs, parameter.name);
                }

                switch (parameter.variableType) {
                    case VariableType.inParameter:
                        break;
                    case VariableType.refParameter:
                        break;
                    case VariableType.outParameter:
                        pb.SetCustomAttribute(typeof(System.Runtime.InteropServices.OutAttribute).GetConstructor(new Type[0]), new byte[0]);
                        break;
                    case VariableType.paramsParameter:
                        pb.SetCustomAttribute(typeof(ParamArrayAttribute).GetConstructor(new Type[0]), new byte[0]);
                        break;
                    case VariableType.argListParameter:
                    default:
                        break;
                }
            }

        }

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public override void emitBody() {
            var isToplever = container.reference.memberType == MemberType.@namespace;

            // 生成 CallingConventions。
            CallingConventions convt = CallingConventions.Standard;
            if (reference.parameters.Length > 0 && reference.parameters[reference.parameters.Length - 1].variableType == VariableType.argListParameter) {
                convt = CallingConventions.VarArgs;
            }

            if (modifiers.hasFlag(Modifiers.@static)) {
                convt |= CallingConventions.HasThis;
            }

            // 定义方法。
            if (isToplever) {
                // todo: 全局方法
            } else {
                builder = ((TypeDefinition)container).builder.DefineMethod(reference.name, getMethodAttributes(), convt);
            }

            emitParameters(builder, null);

            // 定义返回值。
            builder.SetReturnType(reference.returnType.metaInfo);

        }

        public override void writeDebugSymbol(MonoSymbolFile file) {
            if (MethodData != null)
                MethodData.WriteDebugSymbol(file);
        }
    }

    /// <summary>
    /// 表示一个方法定义。
    /// </summary>
    public partial class MethodDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取方法属性。
        /// </summary>
        /// <returns></returns>
        protected sealed override MethodAttributes getMethodAttributes() {
            var attrs = base.getMethodAttributes();
            if (implementing != null) {
                attrs |= MethodAttributes.NewSlot;
            }
            return attrs;
        }

        public sealed override void emitBody() {

            base.emitBody();

            // 创建泛型形参。
            List<MemberReference.GenericParameter> tps = ListObjectPool<MemberReference.GenericParameter>.alloc();
            base.appedAllGenericParameters(tps);
            if (tps.Count > 0) {
                var gps = builder.DefineGenericParameters(base.getGenericParameterNames(tps));
                base.createGenericParametersBuilder(tps, gps);
                base.emitGenericParameters(gps);
            }
            ListObjectPool<MemberReference.GenericParameter>.free(tps);

        }

    }

    /// <summary>
    /// 表示一个构造函数定义。
    /// </summary>
    public partial class ConstructorDefinition {

    }

    /// <summary>
    /// 表示操作符重载定义。
    /// </summary>
    public partial class OperatorDefinition {

        /// <summary>
        /// 根据当前成员修饰符获取方法属性。
        /// </summary>
        /// <returns></returns>
        protected sealed override MethodAttributes getMethodAttributes() {
            return getMethodAttributes() | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
        }

    }

    /// <summary>
    /// 表示一个枚举的成员定义。
    /// </summary>
    public partial class EnumMemberDefinition {

        /// <summary>
        /// 获取当前成员对应的构建器。
        /// </summary>
        public FieldBuilder builder {
            get {
                return (FieldBuilder)reference.metaInfo;
            }
            set {
                reference.metaInfo = value;
            }
        }

        /// <summary>
        /// 生成当前主体的代码。
        /// </summary>
        public override void emitBody() {
            Debug.Assert(containerType != null, "枚举成员容器一定是枚举");
            builder = containerType.builder.DefineField(reference.name, reference.returnType.metaInfo, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
        }

    }

    #endregion

}
